<template>
  <AuFormModal
    ref="formModalRef"
    v-model="showModal"
    :title="title"
    :formList="formList"
    :formData="selfFormData"
    :modalProps="{
      width: 600
    }"
    :formProps="{
      class: '!w-[586px]'
    }"
    @handleConfirm="handleConfirm"
  />
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  getCurrentInstance,
  h,
  nextTick,
  onBeforeMount,
  onMounted,
  ref,
  watch
} from "vue";
import { AuFormModal } from "@/components/AuModal";
import { inputProps, selectProps } from "@/components/AuForm/type";
import { ElButton, ElMessage } from "element-plus";
import {
  deviceActivation,
  deviceEnterAdd,
  DeviceEnterProp,
  deviceEnterUpd,
  deviceRedistribution,
  getDeviceEnterList
} from "@/api/factory/device";
import { businessGetList } from "@/api/factory/business";
import { useI18n } from "vue-i18n";
import { DEVICE_TYPE_ENUM } from "@/utils/constants";

type FormProps = [
  inputProps,
  inputProps,
  inputProps,
  inputProps,
  inputProps,
  inputProps,
  inputProps,
  selectProps
];

export default defineComponent({
  name: "AddEditModal",
  components: {
    AuFormModal
  },
  props: {
    modelValue: {
      type: Boolean,
      default: false
    },
    formData: {
      type: Object as PropType<DeviceEnterProp>,
      default: () => ({})
    }
  },
  emits: ["update:modelValue", "confirm"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const { t } = useI18n();
    const title = ref("");
    const showModal = computed({
      get() {
        return props.modelValue;
      },
      set(value) {
        emit("update:modelValue", value);
      }
    });
    // const showModal = ref(false);
    const show = ref(false);
    const top = ref("20%");
    const ButtonRender = (disabled: boolean) => {
      return h(
        ElButton,
        {
          type: "primary",
          class: "ml-[8px]",
          disabled,
          onClick: reAddSpec
        },
        t("device_manage.form.reallocate")
      );
    };
    const retMatchLength = (initial: string[], value: string) => {
      let isMatch = false;
      for (let i = 0; i < initial.length; i++) {
        if (value.substring(0, initial[i].length) === initial[i]) {
          isMatch = true;
          break;
        }
      }
      return isMatch;
    };
    const formList = ref<FormProps>([
      {
        type: "input",
        key: "device_model",
        label: "device_manage.form.device_model",
        placeholder: "device_manage.form.device_model_placeholder",
        required: true,
        rules: [
          {
            validator: (rule: any, value: string, callback: any) => {
              const modelInitial = ["G", "H", "S", "E", "tp", "BAT", "JU"];
              if (!value) {
                callback(new Error(t("device_manage.form.device_model_empty")));
              }
              const modelVal = value.split("ATT-")[1] ?? "";
              if (value.length < 5 || value.length > 100) {
                callback(
                  new Error(t("device_manage.form.device_model_length"))
                );
              } else if (value.indexOf("ATT-") == -1) {
                callback(
                  new Error(t("device_manage.form.device_model_format"))
                );
              } else if (modelVal.length < 2) {
                callback(
                  new Error(t("device_manage.form.device_model_length_short"))
                );
              } else if (!retMatchLength(modelInitial, modelVal)) {
                callback(
                  new Error(t("device_manage.form.device_model_letter"))
                );
              } else {
                callback();
              }
            },
            trigger: "blur"
          }
        ]
      },
      {
        type: "input",
        key: "device_id",
        label: "device_manage.form.device_id",
        placeholder: "device_manage.form.device_id_placeholder",
        required: true,
        rules: [
          {
            validator: (rule: any, value: string, callback: any) => {
              if (!value) {
                callback(new Error(t("device_manage.form.device_id_empty")));
              }
              const idInitial = ["U", "V", "K", "E", "tp", "BAT", "JU"];
              const idVal = value.split("ATT-")[1] ?? "";
              if (value.length < 5 || value.length > 100) {
                callback(new Error(t("device_manage.form.device_id_length")));
              } else if (value.indexOf("ATT-") == -1) {
                callback(new Error(t("device_manage.form.device_id_format")));
              } else if (idVal.length < 2) {
                callback(
                  new Error(t("device_manage.form.device_id_length_short"))
                );
              } else if (!retMatchLength(idInitial, idVal)) {
                callback(new Error(t("device_manage.form.device_id_letter")));
              } else if (
                devEnterList.value.includes(value) &&
                value != props.formData?.device_id
              ) {
                callback(new Error(t("device_manage.form.device_id_exists")));
              } else {
                callback();
              }
            },
            trigger: "blur"
          }
        ]
      },
      {
        type: "input",
        key: "device_model_info",
        label: "device_manage.form.model_description",
        placeholder: "device_manage.form.model_description_placeholder"
      },
      {
        type: "input",
        key: "business_id",
        label: "device_manage.form.business_id",
        disabled: true,
        hidden: true
      },
      {
        type: "input",
        key: "business_name",
        label: "device_manage.form.business_name",
        disabled: true,
        hidden: true
      },
      {
        type: "input",
        key: "store_id",
        label: "device_manage.form.store_id",
        disabled: true,
        hidden: true
      },
      {
        type: "input",
        key: "store_name",
        label: "device_manage.form.store_name",
        disabled: true,
        hidden: true
      },
      {
        type: "select",
        key: "business_val",
        label: "device_manage.form.business_distribution",
        placeholder: "device_manage.form.business_distribution_placeholder",
        valueKey: "id",
        labelKey: "brand",
        options: [],
        disabled: true,
        hidden: true,
        style: {
          width: "194px"
        },
        behindRender: () => ButtonRender(false)
      }
    ]);
    const selfFormData = ref({});
    const formModalRef = ref();
    const businessList = ref([]);
    const devEnterList = ref([]);

    watch(
      () => [props.modelValue, props.formData],
      ([val, row]) => {
        if (val) {
          title.value = row.id
            ? t("device_manage.form.edit_device")
            : t("device_manage.form.add_device");
          selfFormData.value = {
            ...row.device,
            ...row,
            business_val: row.device?.business_id
          };

          const keys = [
            "device_model",
            "device_id",
            "business_id",
            "business_name",
            "store_id",
            "store_name",
            "business_val"
          ];
          show.value = true;
          nextTick(() => {
            formModalRef.value?.setFormProps(keys, {
              device_model: { disabled: !!row.device },
              device_id: { disabled: !!row.device },
              business_id: { hidden: !row.device },
              business_name: { hidden: !row.device },
              store_id: { hidden: !row.device },
              store_name: { hidden: !row.device },
              business_val: {
                hidden: !row.device,
                options: businessList.value,
                disabled: !!row.device?.store_id,
                behindRender: () => ButtonRender(!!row.device?.store_id)
              }
            });
          });
          getDeviceEnter();
        } else {
          formModalRef.value?.reset();
        }
      }
    );

    const reAddSpec = async () => {
      const formData = formModalRef.value.getFormData() as DeviceEnterProp;
      const { device_id, device_model, business_val } = formData;
      if (!business_val) {
        ElMessage.error(
          t("device_manage.form.business_distribution_placeholder")
        );
        return;
      }

      proxy.$auMessageBox
        .confirm(t("device_manage.form.reallocate_confirm"), t("notice.title"))
        .then(() => {
          const param = {
            device_id,
            business_id: business_val
          };
          deviceRedistribution(param).then(res => {
            ElMessage.success(t("device_manage.form.reallocate_success"));
            emit("confirm");
          });
        });
    };

    function deviceActivationData(
      device_id: string,
      business_id: string,
      brand: string
    ) {
      return new Promise((resolve, reject) => {
        let urlData = new URLSearchParams();
        urlData.append("device_id", device_id);
        urlData.append("business_id", business_id);
        urlData.append("brand", brand);
        deviceActivation(urlData).then(
          function (response) {
            var d = response.data;
            if (d != null) {
              if (d.status == "ok") {
                resolve(true);
                return;
              }
            }
            resolve(false);
          },
          function (error) {
            resolve(false);
          }
        );
      });
    }

    const handleConfirm = async (data: {
      id: string;
      device_id: string;
      device_model: string;
      device_model_info: string;
    }) => {
      const service = data.id ? deviceEnterUpd : deviceEnterAdd;
      const typeList = {
        // G: t("device_manage.form.device_type_cabinet"),
        // H: t("device_manage.form.device_type_mixer"),
        // S: t("device_manage.form.device_type_tea"),
        // E: t("device_manage.form.device_type_expiry"),
        // tp: t("device_manage.form.device_type_powder"),
        // BAT: t("device_manage.form.device_type_ingredient"),
        // JU: t("device_manage.form.device_type_pulper")
        G: DEVICE_TYPE_ENUM.CABINET,
        H: DEVICE_TYPE_ENUM.MIXING_MAT,
        S: DEVICE_TYPE_ENUM.MAKE_TEA,
        E: DEVICE_TYPE_ENUM.EXPIRY,
        tp: DEVICE_TYPE_ENUM.TEA_POWDER,
        BAT: DEVICE_TYPE_ENUM.MIXING,
        JU: DEVICE_TYPE_ENUM.PULPER
      };
      const deviceModelSplit = data.device_model.split("ATT-");
      let device_type;
      for (const key in typeList) {
        const devKey = deviceModelSplit[1].substring(0, key.length);
        if (devKey === key) {
          device_type = typeList[key];
        }
      }
      const param = {
        hiddenDeviceType: true
      };
      if (data.id) {
        param["device_type"] = device_type;
        param["id"] = data.id;
        param["device_id"] = data.device_id;
        param["device_model"] = data.device_model;
        param["device_model_info"] = data.device_model_info;
      } else {
        param["jsonData"] = JSON.stringify([{ ...data, device_type }]);
      }

      const res = await service(param);
      if (res.code == 200) {
        ElMessage({
          message: t("device_manage.form.save_success"),
          type: "success"
        });
        if (device_type === DEVICE_TYPE_ENUM.MIXING_MAT) {
          deviceActivationData(data.device_id, "26", "").then(result => {
            if (!result) {
              ElMessage(t("device_manage.form.device_activation_failed"));
            }
            emit("update:modelValue", false);
            emit("confirm");
          });
        } else {
          emit("update:modelValue", false);
          emit("confirm");
        }
      }
    };

    const getBusinessList = () => {
      businessGetList({ start_page: 1, size: 0 }).then(res => {
        businessList.value = res.data;
      });
    };
    const getDeviceEnter = () => {
      getDeviceEnterList({ start_page: 1, size: 0 }).then(res => {
        devEnterList.value = res.data.map(v => {
          return v.device_id;
        });
      });
    };

    onBeforeMount(() => {
      getBusinessList();
      // 解决弹窗显示错位问题，先弹出一次，再关闭
      // showModal.value = true;
      // nextTick(() => {
      //   showModal.value = false;
      // });
    });

    return {
      title,
      top,
      showModal,
      show,
      formList,
      formModalRef,
      selfFormData,
      handleConfirm
    };
  }
});
</script>
